package com.clarence.dada.modular.system.dict.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.base.PageResult;
import com.clarence.dada.core.redis.RedisOperatorApi;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.enums.YesOrNotEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.factory.PageFactory;
import com.clarence.dada.core.factory.PageResultFactory;
import com.clarence.dada.modular.system.dict.entity.SysDictEntity;
import com.clarence.dada.modular.system.dict.entity.req.DictReq;
import com.clarence.dada.modular.system.dict.entity.resp.SysDictResp;
import com.clarence.dada.modular.system.dict.mapper.DictMapper;
import com.clarence.dada.modular.system.dict.service.DictService;
import com.clarence.dada.modular.system.dict.service.DictTypeService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 字典 服务实现类
 *
 * @author GD
 * @since 2020/12/26 22:36
 */
@Service
@Slf4j
public class DictServiceImpl extends ServiceImpl<DictMapper, SysDictEntity> implements DictService {

    @Resource
    private DictTypeService dictTypeService;

    //    @Resource(name = "defaultStringCacheOperator")
    private RedisOperatorApi<String> defaultStringCacheOperator;

    private static final String CACHE_PREFIX = "dict:";

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dictAdd(DictReq req) {
        // 校验字典重复
        this.validateRepeat(req);
        this.save(Convert.convert(SysDictEntity.class, req));
    }

    @Override
    public void dictDelete(DictReq req) {
        SysDictEntity sysDictEntity = this.querySysDict(req);
        sysDictEntity.setDelFlag(YesOrNotEnum.Y.getCode());
        this.updateById(sysDictEntity);

        // 清除缓存中的字典值
//        defaultStringCacheOperator.remove(CACHE_PREFIX + sysDictEntity.getDictTypeCode() + "|" + sysDictEntity.getDictCode());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void dictEdit(DictReq req) {
        // 校验字典重复
        this.validateRepeat(req);

        SysDictEntity sysDictEntity = this.querySysDict(req);
        BeanUtil.copyProperties(req, sysDictEntity);
        // 不能修改字典类型和编码
        sysDictEntity.setDictTypeCode(null);
        sysDictEntity.setDictCode(null);
        this.updateById(sysDictEntity);

        // 清除缓存中的字典值
//        defaultStringCacheOperator.remove(CACHE_PREFIX + sysDictEntity.getDictTypeCode() + "|" + sysDictEntity.getDictCode());
    }

    @Override
    public SysDictResp dictDetail(DictReq req) {
        SysDictEntity sysDictEntity = this.getOne(this.createWrapper(req), false);
        if (ObjectUtil.isEmpty(sysDictEntity)) {
            return null;
        } else {
            return Convert.convert(SysDictResp.class, sysDictEntity);
        }
    }

    @Override
    public List<SysDictResp> dictList(DictReq req) {
        List<SysDictEntity> sysDictList = this.list(this.createWrapper(req));
        return Convert.convert(new TypeReference<>() {}, sysDictList);
    }

    @Override
    public PageResult<SysDictResp> dictPage(DictReq req) {
        Page<SysDictEntity> page = this.page(PageFactory.defaultPage(), this.createWrapper(req));
        List<SysDictResp> respList = Convert.convert(new TypeReference<>() {}, page.getRecords());
        return PageResultFactory.result(page, respList);
    }

//
//    @Override
//    public List<TreeDictInfo> getTreeDictList(DictReq req) {
//
//        // 获取字典类型下所有的字典
//        List<SysDictEntity> sysDictList = this.findList(dictReq);
//        if (sysDictList == null || sysDictList.isEmpty()) {
//            return new ArrayList<>();
//        }
//
//        // 构造树节点信息
//        ArrayList<TreeDictInfo> treeDictInfos = new ArrayList<>();
//        for (SysDictEntity sysDictEntity : sysDictList) {
//            TreeDictInfo treeDictInfo = new TreeDictInfo();
//            treeDictInfo.setDictId(sysDictEntity.getDictId());
//            treeDictInfo.setDictCode(sysDictEntity.getDictCode());
//            treeDictInfo.setDictParentId(sysDictEntity.getDictParentId());
//            treeDictInfo.setDictName(sysDictEntity.getDictName());
//            treeDictInfos.add(treeDictInfo);
//        }
//
//        // 构建菜单树
//        return new DefaultTreeBuildFactory<TreeDictInfo>().doTreeBuild(treeDictInfos);
//    }
//
//    @Override
//    public String getDictName(String dictTypeCode, String dictCode) {
//        String dictName = defaultStringCacheOperator.get(CACHE_PREFIX + dictTypeCode + "|" + dictCode);
//        if (StrUtil.isNotEmpty(dictName)) {
//            return dictName;
//        }
//        LambdaQueryWrapper<SysDictEntity> sysDictLambdaQueryWrapper = new LambdaQueryWrapper<>();
//        sysDictLambdaQueryWrapper.eq(SysDictEntity::getDictTypeCode, dictTypeCode);
//        sysDictLambdaQueryWrapper.eq(SysDictEntity::getDictCode, dictCode);
//        sysDictLambdaQueryWrapper.ne(SysDictEntity::getDelFlag, YesOrNotEnum.Y.getCode());
//
//        List<SysDictEntity> list = this.list(sysDictLambdaQueryWrapper);
//
//        // 如果查询不到字典，则返回空串
//        if (list.isEmpty()) {
//            return StrUtil.EMPTY;
//        }
//
//        // 字典code存在多个重复的，返回空串并打印错误日志
//        if (list.size() > 1) {
//            log.error(DictExceptionEnum.DICT_CODE_REPEAT.getUserTip(), "", dictCode);
//            return StrUtil.EMPTY;
//        }
//
//        dictName = list.get(0).getDictName();
//        defaultStringCacheOperator.put(CACHE_PREFIX + dictTypeCode + "|" + dictCode, dictName);
//        if (dictName != null) {
//            return dictName;
//        } else {
//            return StrUtil.EMPTY;
//        }
//    }
//
//    @Override
//    public List<SimpleDict> getDictDetailsByDictTypeCode(String dictTypeCode) {
//        DictReq req = new DictReq();
//        dictReq.setDictTypeCode(dictTypeCode);
//        LambdaQueryWrapper<SysDictEntity> wrapper = createWrapper(dictReq);
//        List<SysDictEntity> dictList = this.list(wrapper);
//        if (dictList.isEmpty()) {
//            return new ArrayList<>();
//        }
//        ArrayList<SimpleDict> simpleDictList = new ArrayList<>();
//        for (SysDictEntity sysDictEntity : dictList) {
//            SimpleDict simpleDict = new SimpleDict();
//            simpleDict.setCode(sysDictEntity.getDictCode());
//            simpleDict.setName(sysDictEntity.getDictName());
//            simpleDictList.add(simpleDict);
//        }
//        return simpleDictList;
//    }
//
//    @Override
//    public void deleteByDictId(Long dictId) {
//        this.removeById(dictId);
//    }

    /**
     * 获取详细信息
     *
     * @author GD
     * @since 2021/1/13 10:50
     */
    private SysDictEntity querySysDict(DictReq req) {
        SysDictEntity sysDictEntity = this.getById(req.getDictId());
        if (ObjectUtil.isNull(sysDictEntity)) {
            throw new BusException(ErrorEnum.DICT_NOT_EXISTED);
        }
        return sysDictEntity;
    }

    /**
     * 构建wrapper
     *
     * @author GD
     * @since 2021/1/13 10:50
     */
    private LambdaQueryWrapper<SysDictEntity> createWrapper(DictReq req) {
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(req.getDictId()), SysDictEntity::getDictId, req.getDictId())
                .eq(StrUtil.isNotBlank(req.getDictTypeCode()), SysDictEntity::getDictTypeCode, req.getDictTypeCode())
                .eq(StrUtil.isNotBlank(req.getDictCode()), SysDictEntity::getDictCode, req.getDictCode())
                .like(StrUtil.isNotBlank(req.getDictName()), SysDictEntity::getDictName, req.getDictName())
                .ne(SysDictEntity::getDelFlag, YesOrNotEnum.Y.getCode());
        return queryWrapper;
    }

    /**
     * 检查添加和编辑字典是否有重复的编码和名称
     *
     * @author GD
     * @since 2021/5/12 16:58
     */
    private void validateRepeat(DictReq req) {
        // 检验同字典类型下是否有一样的编码/名称
        LambdaQueryWrapper<SysDictEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDictEntity::getDictTypeCode, req.getDictTypeCode())
                .and(i -> i.eq(SysDictEntity::getDictCode, req.getDictCode())
                        .or()
                        .eq(SysDictEntity::getDictName, req.getDictName()))
                .ne(ObjectUtil.isNotEmpty(req.getDictId()), SysDictEntity::getDictId, req.getDictId())
                .ne(SysDictEntity::getDelFlag, YesOrNotEnum.Y.getCode());
        if (this.count(queryWrapper) > 0) {
            throw new BusException(ErrorEnum.DICT_CODE_OR_NAME_REPEAT);
        }
    }
}
